package com.morizhang.usersys.api;

import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.morizhang.usersys.api.bean.ApiDefinitionHolder;
import com.morizhang.usersys.api.bean.ErrorDefinition;
import com.morizhang.usersys.api.bean.ErrorDefinitionHolder;
import com.morizhang.usersys.api.bean.UserSysException;
import com.morizhang.usersys.api.utils.ErrorUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;

@RestController
public class ApiController extends AbstractApiController{

    @RequestMapping("/api")
    public ResponseEntity<Object> api(HttpServletRequest request, @RequestBody String requestParams) {
        ApiParams apiParams = createApiParams(request, requestParams);
        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);

        try {
            requestValidate(requestParams);
        } catch (UserSysException userSysException) {
            ErrorDefinition error = userSysException.getErrorDefinition();
            JSONObject responseData = ErrorUtils.convertErrorToJsonForm(error);
            responseData.put("isSuccess", "fail");
            return new ResponseEntity<Object>(responseData, headers, HttpStatus.BAD_REQUEST);
        }

        JSONObject paramJson = JSONObject.parseObject(requestParams, Feature.OrderedField);
        String requestService = paramJson.getString("requestService");
        IService service = ApiDefinitionHolder.get(requestService);
        ApiResult result = null;
        try {
            result = service.callService(apiParams.getRequestParams());
        } catch (Exception exception) {
            exception.printStackTrace();
        }

        if (result.isSuccess()) {
            JSONObject responseData = new JSONObject();
            responseData.put("isSuccess", "success");
            responseData.put("data", result.getData());
            return new ResponseEntity<Object>(responseData, headers, HttpStatus.OK);
        } else {
            ErrorDefinition error = result.getException().getErrorDefinition();
            JSONObject responseData = ErrorUtils.convertErrorToJsonForm(error);
            responseData.put("isSuccess", "fail");
            return new ResponseEntity<Object>(responseData, headers, HttpStatus.BAD_REQUEST);
        }
    }

    private void requestValidate(String requestParams) throws UserSysException {
        JSONObject paramJson;
        try {
            paramJson = JSONObject.parseObject(requestParams, Feature.OrderedField);
        }
        catch (JSONException jsonException) {
            ErrorDefinition error = ErrorDefinitionHolder.get("INVALID_FORM");
            UserSysException userSysException = new UserSysException();
            userSysException.setErrorDefinition(error);
            throw userSysException;
        }
        if (paramJson.get("requestService") == null) {
            ErrorDefinition error = ErrorDefinitionHolder.get("NO_REQUEST_SERVICE");
            UserSysException userSysException = new UserSysException();
            userSysException.setErrorDefinition(error);
            throw userSysException;
        }
        if (paramJson.get("requestMethod") == null) {
            ErrorDefinition error = ErrorDefinitionHolder.get("NO_REQUEST_METHOD");
            UserSysException userSysException = new UserSysException();
            userSysException.setErrorDefinition(error);
            throw userSysException;
        }
        if (paramJson.get("data") == null) {
            ErrorDefinition error = ErrorDefinitionHolder.get("NO_DATA");
            UserSysException userSysException = new UserSysException();
            userSysException.setErrorDefinition(error);
            throw userSysException;
        }
    }

}
